/*
 * ModelCC, distributed under ModelCC Shared Software License, www.modelcc.org
 */

package org.modelcc.language.factory;

import java.io.Serializable;
import java.util.List;

import org.modelcc.language.metamodel.LanguageElement;
import org.modelcc.lexer.recognizer.PatternRecognizer;

/**
 * Symbol identifier.
 * 
 * @author Luis Quesada (lquesada@modelcc.org)
 */
public class SymbolIdentifier implements Serializable {

    /**
     * ModelElement type.
     */
    private SymbolType type;

    /**
     * ModelElement.
     */
    private LanguageElement element;

    /**
     * Separator list.
     */
    private List<PatternRecognizer> listSeparator;

    /**
     * Reference.
     */
    private boolean reference;
    
    /**
     * Constructor
     * @param type the element type
     * @param element the element
     * @param listSeparator the separator list
     * @param reference whether this element is a reference. 
     */
    public SymbolIdentifier(SymbolType type,LanguageElement element,List<PatternRecognizer> listSeparator,boolean reference) 
    {
        this.type = type;
        this.element = element;
        this.listSeparator = listSeparator;
        this.reference = reference;
    }

    public SymbolType getType() {
        return type;
    }

    public LanguageElement getElement() {
        return element;
    }

    public List<PatternRecognizer> getListSeparator() {
        return listSeparator;
    }

    @Override
    public String toString() 
    {
        String r = "";

        if (reference)
            r = "&";
        
        return r + getElement().getElementClass().getSimpleName() + ":" + type.name();
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final SymbolIdentifier other = (SymbolIdentifier) obj;
        if (this.type != other.type) {
            return false;
        }
        if (this.element != other.element && (this.element == null || !this.element.equals(other.element))) {
            return false;
        }
        if (this.listSeparator != other.listSeparator && (this.listSeparator == null || !this.listSeparator.equals(other.listSeparator))) {
            return false;
        }
        if (this.reference != other.reference) {
            return false;
        }
        return true;
    }

    @Override
    public int hashCode() {
        int hash = 7;
        hash = 79 * hash + (this.type != null ? this.type.hashCode() : 0);
        hash = 79 * hash + (this.element != null ? this.element.hashCode() : 0);
        hash = 79 * hash + (this.listSeparator != null ? this.listSeparator.hashCode() : 0);
        hash = 79 * hash + (this.reference ? 1 : 0);
        return hash;
    }
}
